package com.diana.filter;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.Condition;
import com.diana.common.StatusEnums;
import com.diana.common.TokenUtils;
import com.diana.common.Utils;
import com.diana.entity.ManagerMenu;
import com.diana.mapper.ManagerRoleMenuMapper;
import com.diana.service.ManagerMenuService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class MainFilter implements Filter {

	private static final Logger LOG = LoggerFactory.getLogger(MainFilter.class);
	@Autowired
	private ManagerMenuService managerMenuService;
	@Autowired
	private ManagerRoleMenuMapper managerRoleMenuMapper;

	@Override
	public void destroy() {
		LOG.info("MainFilter destroy()");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;
		String url = httpRequest.getRequestURL().toString();
		LOG.info(url);
		String originHeader =  httpRequest.getHeader("Origin");
		httpResponse.setHeader("Access-Control-Allow-Headers",
				"Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token,ManagerId,ManagerToken");// 表明服务器支持的所有头信息字段
		httpResponse.setHeader("Access-Control-Allow-Origin", originHeader);
		httpResponse.setContentType("application/json;charset=UTF-8");
		httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
		httpResponse.setHeader("Access-Control-Max-Age", "7500");
		httpResponse.setHeader("Access-Control-Allow-Credentials", "true"); // 如果要把Cookie发到服务器，需要指定Access-Control-Allow-Credentials字段为true;
		httpResponse.setHeader("XDomainRequestAllowed", "1");
		//httpResponse.addHeader("Access-Control-Expose-Headers", "REDIRECT,CONTEXTPATH");
		int result = checkToken(httpRequest);
		JSONObject jo = new JSONObject();
        String managerId = httpRequest.getHeader("managerId");

		switch (result){
			case StatusEnums.CheckTokenStatus.用户未登录 :
				jo.put("code","3001");
				jo.put("msg","用户未登录");
				Utils.writeJson(httpResponse,jo);
				/*httpResponse.setHeader("REDIRECT", "REDIRECT");
				httpResponse.setHeader("CONTENTPATH", "http://localhost:6060/html/login.html");
				httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);*/
				return;
			case StatusEnums.CheckTokenStatus.令牌验证有误://
				jo.put("code","3001");
				jo.put("msg","令牌验证有误");
				Utils.writeJson(httpResponse,jo);
				return;
			case StatusEnums.CheckTokenStatus.权限不足:
				jo.put("code","0001");
				jo.put("msg","权限不足");
				Utils.writeJson(httpResponse,jo);
				return;
			case StatusEnums.CheckTokenStatus.权限不存在:
				jo.put("code","0001");
				jo.put("msg","权限不存在");
				Utils.writeJson(httpResponse,jo);
				return;
			case StatusEnums.CheckTokenStatus.令牌过期:
				jo.put("code","3001");
				jo.put("msg","令牌过期");
				Utils.writeJson(httpResponse,jo);
				return;
			default:
				if(!Utils.isNullOrEmpty(managerId)&&result==StatusEnums.CheckTokenStatus.验证通过){
				    //如果只设置这里，需要从响应头中获取token
					httpResponse.setHeader("token", TokenUtils.getToken(managerId,StatusEnums.tokenTime));
					//设置这里,前端可response.headers.token获取上面设置的token
                    httpResponse.setHeader("Access-Control-Expose-Headers", "token");
				}
				break;
		}
		chain.doFilter(httpRequest,httpResponse);
	}

	/**
	 * 验证token
	 * @param request
	 * @return
	 */
	private int checkToken(HttpServletRequest request){
		String url = request.getRequestURL().toString();
		url = url.substring(url.indexOf(request.getServerName()));
		url = url.substring(url.indexOf("/"));
		if(url.startsWith("/admin/")){
			String managerId = request.getHeader("managerId");
			String token = request.getHeader("token");
			if(Utils.isEmptyObj(managerId,token)){
				return StatusEnums.CheckTokenStatus.用户未登录;
			}
			int vaildToken = TokenUtils.vaildToken(managerId, token);
			if(vaildToken!=StatusEnums.CheckTokenStatus.验证通过){
				return vaildToken;
			}
			//验证权限
            ManagerMenu managerMenu = managerMenuService.selectOne(Condition.create().setSqlSelect("menuId").eq("permissionUrl", url).eq("status", StatusEnums.CommonStatus.可用));
            if(managerMenu==null){
				return StatusEnums.CheckTokenStatus.权限不存在;
			}
            int havePermission = managerRoleMenuMapper.isHavePermission(managerId, managerMenu.getMenuId());
            if(havePermission>0){
                return StatusEnums.CheckTokenStatus.验证通过;
			}
            return StatusEnums.CheckTokenStatus.权限不足;
		}
		//匿名访问
		return StatusEnums.CheckTokenStatus.匿名访问;
	}

	@Override
	public void init(FilterConfig config) throws ServletException {
		LOG.info("MainFilter init()");
	}
}
